package dao

import (
	"context"
	"sale-admin/internal/dal"
	"sale-admin/internal/models"

	"github.com/golang-module/carbon/v2"
	"github.com/samber/lo"
	"gorm.io/gorm"
)

type RobotSalesInfo struct{}

func (RobotSalesInfo) List(ctx context.Context, query *dal.Query, robotName, goodsID string, containerStatus, containerUseStatus int) (data []*models.MaRobotSalesInfo, err error) {
	m := query.MaRobotSalesInfo

	tx := m.WithContext(ctx).
		Where(m.RobotName.Eq(robotName)).
		Where(m.GoodsID.Eq(goodsID))
	if containerStatus != 0 {
		tx = tx.Where(m.ContainerStatus.Eq(containerStatus))
	}
	if containerUseStatus != 0 {
		tx = tx.Where(m.ContainerUseStatus.Eq(containerUseStatus))
	}
	data, _ = tx.Select(
		m.RobotName,
		m.GoodsID,
		m.ContainerNum,
		m.ContainerStatus,
		m.ContainerUseStatus,
		m.GoodsInventory,
		m.GoodsMaxInventory,
		m.GoodsReserveInventory,
	).Order(m.GoodsInventory.Desc()).
		Find()
	return
}
func (RobotSalesInfo) GetRobotInventoryList(ctx context.Context, db *gorm.DB, date string) (data []*models.MaRobotSalesInfo, err error) {
	m := dal.Use(db).MaRobotSalesInfo

	end := carbon.Parse(date).EndOfDay().ToStdTime()
	data, _ = m.WithContext(ctx).
		Where(m.AddTime.Lte(end)).
		Where(m.ContainerStatus.Eq(1)).
		Where(m.ContainerUseStatus.Eq(1)).
		Select(
			m.RobotName,
			m.GoodsInventory.Sum().As(m.GoodsInventory.ColumnName().String()),
			m.GoodsMaxInventory.Sum().As(m.GoodsMaxInventory.ColumnName().String()),
		).
		Group(m.RobotName).
		Find()
	return
}

// 获取0库存货道列表
func (RobotSalesInfo) GetZeroContainerNumBySalesID(ctx context.Context, query *dal.Query, salesID string) (res []int, err error) {
	if salesID == "" {
		return
	}
	m := query.MaRobotSalesInfo
	m.WithContext(ctx).
		Where(m.SalesID.Eq(salesID)).
		Where(m.ContainerStatus.Eq(1)).    // 0-下架 1-上架
		Where(m.ContainerUseStatus.Eq(1)). // 1 正常 2 禁用
		Where(m.GoodsInventory.Eq(0)).     // 货道剩余库存为0
		Group(m.ContainerNum).
		Pluck(m.ContainerNum, &res)
	return
}

// 获取故障货道列表
func (RobotSalesInfo) GetErrorContainerNumsBySalesID(ctx context.Context, query *dal.Query, salesID string) (res []int, err error) {
	if salesID == "" {
		return
	}
	m := query.MaRobotSalesInfo
	m.WithContext(ctx).
		Where(m.SalesID.Eq(salesID)).
		Where(m.ContainerStatus.Eq(1)).    // 0-下架 1-上架
		Where(m.ContainerUseStatus.Eq(2)). // 1 正常 2 禁用
		Pluck(m.ContainerNum, &res)
	return
}

type MaRobotSalesInfoDetail struct {
	GoodsName1          string `json:"goods_name1"`
	GoodsID             string `json:"goods_id"`
	SalesID             string `json:"sales_id"`
	MerchantID          string `json:"merchant_id"`
	RobotName           string `json:"robot_name"`
	LocationID          string `json:"location_id"`
	ContainerStatus     int    `json:"container_status"`
	ContainerNum        int    `json:"container_num"` // 货道号
	RobotGoodsInventory int    `json:"robot_goods_inventory"`
	GoodsMaxInventory   int    `json:"goods_max_inventory"`
}

// 获取空货库存信息[商品分组]
func (RobotSalesInfo) GetEmptyStockList(ctx context.Context, query *dal.Query) (
	res []MaRobotSalesInfoDetail, Count int64, err error,
) {
	r := query.MaRobot
	s := query.MaRobotSalesInfo
	r.WithContext(ctx).LeftJoin(s, r.SalesID.EqCol(s.SalesID)).
		Where(r.Deleted.Eq(0)).
		Where(r.RobotType.In([]string{"0", "5", "11"}...)).
		Where(s.ContainerStatus.Eq(1), s.ContainerUseStatus.Eq(1)).
		Where(s.GoodsMaxInventory.Gt(0)).
		Select(s.GoodsID, r.SalesID, r.MerchantID, r.RobotName, s.ContainerStatus, s.ContainerNum,
			r.Areas3.As("location_id"), s.GoodsInventory.Sum().As("robot_goods_inventory"),
			s.GoodsMaxInventory.Sum().As("goods_max_inventory")).
		Group(r.RobotName, s.GoodsID).
		Having(s.GoodsInventory.Sum().Eq(0)).
		Order(r.RobotName, s.GoodsID).
		Scan(&res)
	var goodsIDList = []string{}
	for _, v := range res {
		if !lo.Contains(goodsIDList, v.GoodsID) {
			goodsIDList = append(goodsIDList, v.GoodsID)
		}
	}
	var goodsList = []struct {
		GoodsID    string
		GoodsName1 string
	}{}
	g := query.MaGoodsInfo
	g.WithContext(ctx).
		Where(g.GoodsID.In(goodsIDList...)).
		Select(g.GoodsID, g.GoodsName1).
		Scan(&goodsList)
	var goodsNameMap = make(map[string]string)
	for _, v := range goodsList {
		goodsNameMap[v.GoodsID] = v.GoodsName1
	}
	for i := range res {
		if _, ok := goodsNameMap[res[i].GoodsID]; ok {
			res[i].GoodsName1 = goodsNameMap[res[i].GoodsID]
		}
	}
	return res, int64(len(res)), nil
}
